/**
 * @author luguoxiang
 * @date 2022/7/5
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
import { RangeInput } from 'tdesign-vue-next';
import {
  deepCopy,
  FilterTypeEnum,
  IConfigSchema,
  ISearchSchema,
  LgRangeDate,
  LgRangeDateProps,
  LgRangeTime,
  LgRangeTimeProps,
  toOptions,
} from '@/soar';

/**
 * 生成搜索栏配置
 * @param config
 */
function toSearch(config: IConfigSchema<unknown> | ISearchSchema<unknown>): object {
  let search;
  // @ts-ignore
  if (config.search) {
    // @ts-ignore
    search = config.search;
    search.params ??= config.params;
    search = deepCopy(search, true);
    // 基本字段复制
    search.field ??= config.field;
    search.label ??= config.label;
    search.dataType ??= config.dataType;
    search.predicate ??= config.predicate;
  } else {
    search = deepCopy(config, true);
    delete search.detail;
    delete search.form;
    delete search.table;
  }
  delete search.order;

  // 插槽处理
  if (typeof search.slots === 'string') {
    search.slots = { default: search.slots };
  } else {
    search.slots ??= {};
  }

  // 自动配置组件
  if (!search.slots.default && !search.component) {
    switch (search.dataType) {
      case 'number':
        search.component = RangeInput;
        search.componentProps = {
          clearable: true,
          placeholder: ['最小值', '最大值'],
          ...search.componentProps,
        };
        search.searchType = FilterTypeEnum.BETWEEN;
        break;
      case 'datetime':
        search.component = LgRangeDate;
        search.componentProps = {
          dateProps: {
            clearable: true,
            format: search.params,
            valueType: search.params,
            allowInput: true,
            enableTimePicker: true,
          },
          placeholder: ['开始时间', '结束时间'],
          ...search.componentProps,
        } as LgRangeDateProps;
        search.searchType = FilterTypeEnum.BETWEEN;
        break;
      case 'date':
        search.component = LgRangeDate;
        search.componentProps = {
          dateProps: {
            clearable: true,
            format: search.params,
            valueType: search.params,
            allowInput: true,
          },
          placeholder: ['开始日期', '结束日期'],
          ...search.componentProps,
        } as LgRangeDateProps;
        search.searchType = FilterTypeEnum.BETWEEN;
        break;
      case 'time':
        search.component = LgRangeTime;
        search.componentProps = {
          timeProps: {
            clearable: true,
            format: search.params,
            allowInput: true,
          },
          placeholder: ['开始时间', '结束时间'],
          ...search.componentProps,
        } as LgRangeTimeProps;
        search.searchType = FilterTypeEnum.BETWEEN;
        break;
      case 'boolean':
        search.component ??= 't-radio-group';
        if (typeof search.componentProps !== 'function') {
          search.componentProps = {
            allowUncheck: true,
            options: search.params
              ? toOptions(search.params)
              : [
                  { value: 1, label: '是' },
                  { value: 0, label: '否' },
                ],
            ...search.componentProps,
          };
        }
        break;
      default:
        if (typeof search.componentProps !== 'function') {
          search.componentProps = {
            clearable: true,
            ...search.componentProps,
          };
        }
        break;
    }
  }

  // 自动配置查询方式
  if (!search.searchType) {
    if (search.dataType === 'number' || search.dataType === 'boolean') {
      search.searchType = FilterTypeEnum.EQ;
    } else if (search.dataType === 'dict' || search.dataType === 'enum') {
      search.searchType = FilterTypeEnum.IN;
    } else {
      search.searchType = FilterTypeEnum.LIKE;
    }
  }

  return search;
}

/**
 * 获取搜索栏配置
 * @param fieldList
 */
export function getSearchs(fieldList: Array<IConfigSchema<unknown> | ISearchSchema<unknown>>): object[] {
  return (
    fieldList
      // 过滤
      .filter((x: any) => x.search !== false)
      // 排序
      .sort((a: any, b: any) => {
        if (a.search) {
          a = a.search;
        }
        if (b.search) {
          b = b.search;
        }
        return (a.order ?? 0) - (b.order ?? 0);
      })
      // 解析
      .map(toSearch)
      .filter((x: any) => x.predicate?.() !== false)
  );
}
